package tbk

import (
	"fmt"
	"net/http"
	"net/url"
	"time"

	"commonUtils/tbk/apis"
	"commonUtils/utils"
)

type TBK struct {
	ID              string    `json:"account" bson:"_id" validate:"required"`
	Pwd             string    `json:"pwd" bson:"pwd" validate:"required"`
	MemberID        string    `json:"memberid" bson:"memberid" validate:"required"`
	HttpValid       bool      `json:"http_valid" bson:"http_valid"`
	Cookies         []string  `json:"cookies" bson:"cookies"`
	LastRequestTime time.Time `json:"last_request_time" bson:"last_request_time"`
	LoginError      string    `json:"login_error" bson:"login_error"`
	APIKey          string    `json:"api_key" bson:"api_key" validate:"required"`
	SecretKey       string    `json:"api_secret" bson:"api_secret" validate:"required"`
	SiteID          string    `json:"site_id" bson:"site_id" validate:"required,number"`
	AdZoneID        string    `json:"ad_zone_id" bson:"ad_zone_id" validate:"required,number"`
	Remark          string    `json:"remark" bson:"remark"`

	http *utils.HTTPClient
	api  *Client
}

const (
	url_check = "https://pub.alimama.com/common/getUnionPubContextInfo.json"
)

func NewTBK(account, pwd, apikey, secretKey string) *TBK {
	var t = &TBK{
		ID:        account,
		Pwd:       pwd,
		APIKey:    apikey,
		SecretKey: secretKey,
		http:      utils.NewHTTPClient(),
		api:       NewClient(apikey, secretKey),
	}
	return t
}

func (t *TBK) Init() {
	if nil == t.api {
		t.api = NewClient(t.APIKey, t.SecretKey)
	}
	if t.http == nil {
		t.http = utils.NewHTTPClient()
	}
	if len(t.Cookies) > 0 {
		t.setCookies()
	}
}

func (t *TBK) CheckApiValiable() error {
	api := apis.NewTaobaoTimeGet()
	var ret *apis.TaobaoTimeGetResponse
	var errRet *ErrorResponse
	t.api.Run(api, &ret, &errRet)
	if errRet != nil {
		return fmt.Errorf(errRet.Result.Msg)
	}
	return nil
}

type UserInfo struct {
	Nick  string `json:"mmNick"`
	ID    int    `json:"memberid"`
	Level int    `json:"tkMemberRank"`
}

func (t *TBK) SetCookies(cookies []string) error {
	t.Cookies = cookies
	return t.setCookies()
}

func (t *TBK) setCookies() error {
	if len(t.Cookies) == 0 {
		return fmt.Errorf("cookie length is 0")
	}
	cookieStr := t.Cookies
	for _, line := range cookieStr {
		cookie := t.http.ParseCookieFromLine(line)
		if nil != cookie {

			var cookieScheme string
			if cookie.Secure {
				cookieScheme = "https"
			} else {
				cookieScheme = "http"
			}
			cookieURL := &url.URL{
				Scheme: cookieScheme,
				Host:   cookie.Domain,
			}

			t.http.SetCookies(cookieURL, []*http.Cookie{cookie})
		}
	}
	return nil
}

func (t *TBK) CheckHttpValiable() error {
	if t.HttpValid && time.Now().Before(t.LastRequestTime.Add(5*time.Minute)) {
		return nil
	}
	t.setCookies()
	ret, _, _, err := t.http.Get(url_check, nil)
	if err != nil {
		return err
	}
	utils.Debug("CheckHttpValiable %s : %s", t.ID, ret)
	data, err := utils.JsonToMap(ret)
	if err != nil {
		return err
	}

	userinfodata, ok := data["data"]
	if ok {
		var userinfo *UserInfo
		userjson, err := utils.ToJson(userinfodata)
		if err != nil {
			return err
		}
		err = utils.ToStruct([]byte(userjson), &userinfo)
		if err != nil {
			return err
		}
		if t.MemberID != fmt.Sprintf("%d", userinfo.ID) {
			return fmt.Errorf("account memberid not match : %s != %d", t.MemberID, userinfo.ID)
		}
		t.HttpValid = true
		t.UpdateLastReq()
		return nil
	}
	return fmt.Errorf("http check failed, ret : %s", ret)
}

func (t *TBK) UpdateLastReq() {
	t.LastRequestTime = time.Now()
}

type LoginResp struct {
	Account string   `json:"account"`
	Cookies []string `json:"cookies"`
	Err     string   `json:"error"`
}
